﻿using AllServer.Core.SqlSugar;
using Mapster;
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Yitter.IdGenerator;

namespace AllServer.Core;

public static class SqlSugarSetup
{
    /// <summary>
    /// SqlSugar 上下文初始化
    /// </summary>
    /// <param name="services"></param>
    public static void AddSqlSugar(this IServiceCollection services)
    {
        //注入sqlsugar
        services.AddSingleton<ISqlSugarClient>(DbContext.Instance);
        // 仓储注册
        services.AddScoped(typeof(SqlSugarRepository<>));
        // 事务与工作单元注册
        services.AddUnitOfWork<SqlSugarUnitOfWork>();

        ////根据数据库表创建实体
        //services.CreateEntities(new GenSqlSuarModelConfig
        //{
        //    DbConfigId = AiCenterDbTypeEnum.GuiYinDB.ToString(),
        //    NameSpace = "AllServer.Core.Entity",
        //    Path = "../AllServer.Core/Entity",
        //    //Tables = new System.Collections.Generic.List<string> { "App_BlackWhite_Config", "App_Country_White" }
        //});

        // 注册雪花Id
        //YitIdHelper.SetIdGenerator(App.GetOptions<SnowIdOptions>());

        //// 自定义 SqlSugar 雪花ID算法
        //SnowFlakeSingle.WorkId = App.GetOptions<SnowIdOptions>().WorkerId;
        //StaticConfig.CustomSnowFlakeFunc = () =>
        //{
        //    return YitIdHelper.NextId();
        //};

        //var dbOptions = App.GetOptions<DbConnectionOptions>();
        //dbOptions.ConnectionConfigs.ForEach(SetDbConfig);

        //SqlSugarScope sqlSugar = new(dbOptions.ConnectionConfigs.Adapt<List<ConnectionConfig>>(), db =>
        //{
        //    dbOptions.ConnectionConfigs.ForEach(config =>
        //    {
        //        var dbProvider = db.GetConnectionScope(config.ConfigId);
        //        SetDbAop(dbProvider, dbOptions.EnableConsoleSql);
        //    });
        //});
        //services.AddSingleton<ISqlSugarClient>(sqlSugar); // 单例注册
        //services.AddScoped(typeof(SqlSugarRepository<>)); // 仓储注册
        //services.AddUnitOfWork<SqlSugarUnitOfWork>(); // 事务与工作单元注册

        //// 初始化数据库表结构及种子数据
        ////dbOptions.ConnectionConfigs.ForEach(config =>
        ////{
        ////    InitDatabase(sqlSugar, config);
        ////});
    }



    /////// <summary>
    ///// 配置连接属性
    ///// </summary>
    ///// <param name="config"></param>
    //public static void SetDbConfig(DbConnectionConfig config)
    //{
    //    var configureExternalServices = new ConfigureExternalServices
    //    {
    //        EntityNameService = (type, entity) => // 处理表
    //        {
    //            entity.IsDisabledDelete = true; // 禁止删除非 sqlsugar 创建的列
    //            // 只处理贴了特性[SugarTable]表
    //            if (!type.GetCustomAttributes<SugarTable>().Any())
    //                return;
    //            if (config.DbSettings.EnableUnderLine && !entity.DbTableName.Contains('_'))
    //                entity.DbTableName = UtilMethods.ToUnderLine(entity.DbTableName); // 驼峰转下划线
    //        },
    //        EntityService = (type, column) => // 处理列
    //        {
    //            // 只处理贴了特性[SugarColumn]列
    //            if (!type.GetCustomAttributes<SugarColumn>().Any())
    //                return;
    //            if (new NullabilityInfoContext().Create(type).WriteState is NullabilityState.Nullable)
    //                column.IsNullable = true;
    //            if (config.DbSettings.EnableUnderLine && !column.IsIgnore && !column.DbColumnName.Contains('_'))
    //                column.DbColumnName = UtilMethods.ToUnderLine(column.DbColumnName); // 驼峰转下划线
    //        }
    //    };
    //    config.ConfigureExternalServices = configureExternalServices;
    //    config.InitKeyType = InitKeyType.Attribute;
    //    config.IsAutoCloseConnection = true;
    //    config.MoreSettings = new ConnMoreSettings
    //    {
    //        SqlServerCodeFirstNvarchar = true // 采用Nvarchar
    //    };
    //}

    ///// <summary>
    ///// 配置Aop
    ///// </summary>
    ///// <param name="db"></param>
    ///// <param name="enableConsoleSql"></param>
    //public static void SetDbAop(SqlSugarScopeProvider db, bool enableConsoleSql)
    //{
    //    var config = db.CurrentConnectionConfig;

    //    // 设置超时时间
    //    db.Ado.CommandTimeOut = 30;

    //    // 打印SQL语句
    //    if (enableConsoleSql)
    //    {
    //        db.Aop.OnLogExecuting = (sql, pars) =>
    //        {
    //            var originColor = Console.ForegroundColor;
    //            if (sql.StartsWith("SELECT", StringComparison.OrdinalIgnoreCase))
    //                Console.ForegroundColor = ConsoleColor.Green;
    //            if (sql.StartsWith("UPDATE", StringComparison.OrdinalIgnoreCase) || sql.StartsWith("INSERT", StringComparison.OrdinalIgnoreCase))
    //                Console.ForegroundColor = ConsoleColor.Yellow;
    //            if (sql.StartsWith("DELETE", StringComparison.OrdinalIgnoreCase))
    //                Console.ForegroundColor = ConsoleColor.Red;
    //            Console.WriteLine("【" + DateTime.Now + "——执行SQL】\r\n" + UtilMethods.GetSqlString(config.DbType, sql, pars) + "\r\n");
    //            Console.ForegroundColor = originColor;
    //            App.PrintToMiniProfiler("SqlSugar", "Info", sql + "\r\n" + db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
    //        };
    //        db.Aop.OnError = ex =>
    //        {
    //            if (ex.Parametres == null) return;
    //            var originColor = Console.ForegroundColor;
    //            Console.ForegroundColor = ConsoleColor.DarkRed;
    //            var pars = db.Utilities.SerializeObject(((SugarParameter[])ex.Parametres).ToDictionary(it => it.ParameterName, it => it.Value));
    //            Console.WriteLine("【" + DateTime.Now + "——错误SQL】\r\n" + UtilMethods.GetSqlString(config.DbType, ex.Sql, (SugarParameter[])ex.Parametres) + "\r\n");
    //            Console.ForegroundColor = originColor;
    //            App.PrintToMiniProfiler("SqlSugar", "Error", $"{ex.Message}{Environment.NewLine}{ex.Sql}{pars}{Environment.NewLine}");
    //        };
    //        db.Aop.OnLogExecuted = (sql, pars) =>
    //        {
    //            // 执行时间超过5秒
    //            if (db.Ado.SqlExecutionTime.TotalSeconds > 5)
    //            {
    //                var fileName = db.Ado.SqlStackTrace.FirstFileName; // 文件名
    //                var fileLine = db.Ado.SqlStackTrace.FirstLine; // 行号
    //                var firstMethodName = db.Ado.SqlStackTrace.FirstMethodName; // 方法名
    //                var log = $"【所在文件名】：{fileName}\r\n【代码行数】：{fileLine}\r\n【方法名】：{firstMethodName}\r\n" + $"【sql语句】：{UtilMethods.GetSqlString(config.DbType, sql, pars)}";
    //                var originColor = Console.ForegroundColor;
    //                Console.ForegroundColor = ConsoleColor.DarkYellow;
    //                Console.WriteLine(log);
    //                Console.ForegroundColor = originColor;
    //            }
    //        };
    //    }
    //    // 数据审计
    //    db.Aop.DataExecuting = (oldValue, entityInfo) =>
    //    {
    //        if (entityInfo.OperationType == DataFilterType.InsertByObject)
    //        {
    //            // 主键(long类型)且没有值的,并且不是自动递增的---赋值雪花Id
    //            if (entityInfo.EntityColumnInfo.IsPrimarykey && entityInfo.EntityColumnInfo.PropertyInfo.PropertyType == typeof(long)
    //            && !entityInfo.EntityColumnInfo.IsIdentity)
    //            {
    //                var id = entityInfo.EntityColumnInfo.PropertyInfo.GetValue(entityInfo.EntityValue);
    //                if (id == null || (long)id == 0)
    //                    entityInfo.SetValue(YitIdHelper.NextId());
    //            }
    //            if (entityInfo.PropertyName == nameof(EntityBase.CreateTime))
    //                entityInfo.SetValue(DateTime.Now);
    //            if (App.User != null)
    //            {
    //                if (entityInfo.PropertyName == nameof(EntityTenantId.TenantId))
    //                {
    //                    var tenantId = ((dynamic)entityInfo.EntityValue).TenantId;
    //                    if (tenantId == null || tenantId == 0)
    //                        entityInfo.SetValue(App.User.FindFirst(ClaimConst.TenantId)?.Value);
    //                }
    //                else if (entityInfo.PropertyName == nameof(EntityBase.CreateUserId))
    //                {
    //                    var createUserId = ((dynamic)entityInfo.EntityValue).CreateUserId;
    //                    if (createUserId == 0 || createUserId == null)
    //                        entityInfo.SetValue(App.User.FindFirst(ClaimConst.UserId)?.Value);
    //                }
    //                else if (entityInfo.PropertyName == nameof(EntityBase.CreateUserName))
    //                {
    //                    var createUserName = ((dynamic)entityInfo.EntityValue).CreateUserName;
    //                    if (string.IsNullOrEmpty(createUserName))
    //                        entityInfo.SetValue(App.User.FindFirst(ClaimConst.RealName)?.Value);
    //                }
    //                else if (entityInfo.PropertyName == nameof(EntityBaseData.CreateOrgId))
    //                {
    //                    var createOrgId = ((dynamic)entityInfo.EntityValue).CreateOrgId;
    //                    if (createOrgId == 0 || createOrgId == null)
    //                        entityInfo.SetValue(App.User.FindFirst(ClaimConst.OrgId)?.Value);
    //                }
    //                else if (entityInfo.PropertyName == nameof(EntityBaseData.CreateOrgName))
    //                {
    //                    var createOrgName = ((dynamic)entityInfo.EntityValue).CreateOrgName;
    //                    if (string.IsNullOrEmpty(createOrgName))
    //                        entityInfo.SetValue(App.User.FindFirst(ClaimConst.OrgName)?.Value);
    //                }
    //            }
    //        }
    //        if (entityInfo.OperationType == DataFilterType.UpdateByObject)
    //        {
    //            if (entityInfo.PropertyName == nameof(EntityBase.UpdateTime))
    //                entityInfo.SetValue(DateTime.Now);
    //            else if (entityInfo.PropertyName == nameof(EntityBase.UpdateUserId))
    //                entityInfo.SetValue(App.User?.FindFirst(ClaimConst.UserId)?.Value);
    //            else if (entityInfo.PropertyName == nameof(EntityBase.UpdateUserName))
    //                entityInfo.SetValue(App.User?.FindFirst(ClaimConst.RealName)?.Value);
    //        }
    //    };

    //    // 超管排除其他过滤器
    //    if (App.User?.FindFirst(ClaimConst.AccountType)?.Value == ((int)AccountTypeEnum.SuperAdmin).ToString())
    //        return;

    //    // 配置假删除过滤器
    //    db.QueryFilter.AddTableFilter<IDeletedFilter>(u => u.IsDelete == false);

    //    // 配置租户过滤器
    //    var tenantId = App.User?.FindFirst(ClaimConst.TenantId)?.Value;
    //    if (!string.IsNullOrWhiteSpace(tenantId))
    //        db.QueryFilter.AddTableFilter<ITenantIdFilter>(u => u.TenantId == long.Parse(tenantId));

    //    // 配置用户机构（数据范围）过滤器
    //    SqlSugarFilter.SetOrgEntityFilter(db);

    //    // 配置自定义过滤器
    //    SqlSugarFilter.SetCustomEntityFilter(db);
    //}

    ///// <summary>
    ///// 初始化数据库
    ///// </summary>
    ///// <param name="db"></param>
    ///// <param name="config"></param>
    //private static void InitDatabase(SqlSugarScope db, DbConnectionConfig config)
    //{
    //    SqlSugarScopeProvider dbProvider = db.GetConnectionScope(config.ConfigId);

    //    // 初始化/创建数据库
    //    if (config.DbSettings.EnableInitDb)
    //    {
    //        if (config.DbType != SqlSugar.DbType.Oracle)
    //            dbProvider.DbMaintenance.CreateDatabase();
    //    }

    //    // 初始化表结构
    //    if (config.TableSettings.EnableInitTable)
    //    {
    //        var entityTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.IsDefined(typeof(SugarTable), false))
    //            .WhereIF(config.TableSettings.EnableIncreTable, u => u.IsDefined(typeof(IncreTableAttribute), false)).ToList();

    //        //if (config.ConfigId.ToString() == SqlSugarConst.MainConfigId) // 默认库（有系统表特性、没有日志表和租户表特性）
    //        //    entityTypes = entityTypes.Where(u => u.GetCustomAttributes<SysTableAttribute>().Any() || (!u.GetCustomAttributes<LogTableAttribute>().Any() && !u.GetCustomAttributes<TenantAttribute>().Any())).ToList();

    //        if (config.ConfigId.ToString() == SqlSugarConst.MainConfigId) // 默认库（只有系统表特性，防止初始化老的归因表）
    //            entityTypes = entityTypes.Where(u => u.GetCustomAttributes<SysTableAttribute>().Any()).ToList();
    //        else if (config.ConfigId.ToString() == SqlSugarConst.LogConfigId) // 日志库
    //            entityTypes = entityTypes.Where(u => u.GetCustomAttributes<LogTableAttribute>().Any()).ToList();
    //        else
    //            entityTypes = entityTypes.Where(u => u.GetCustomAttribute<TenantAttribute>()?.configId.ToString() == config.ConfigId.ToString()).ToList(); // 自定义的库

    //        foreach (var entityType in entityTypes)
    //        {
    //            if (entityType.GetCustomAttribute<SplitTableAttribute>() == null)
    //                dbProvider.CodeFirst.InitTables(entityType);
    //            else
    //                dbProvider.CodeFirst.SplitTables().InitTables(entityType);
    //        }
    //    }

    //    // 初始化种子数据
    //    if (config.SeedSettings.EnableInitSeed)
    //    {
    //        var seedDataTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.GetInterfaces().Any(i => i.HasImplementedRawGeneric(typeof(ISqlSugarEntitySeedData<>))))
    //            .WhereIF(config.SeedSettings.EnableIncreSeed, u => u.IsDefined(typeof(IncreSeedAttribute), false)).ToList();

    //        foreach (var seedType in seedDataTypes)
    //        {
    //            var entityType = seedType.GetInterfaces().First().GetGenericArguments().First();
    //            if (config.ConfigId.ToString() == SqlSugarConst.MainConfigId) // 默认库（有系统表特性、没有日志表和租户表特性）
    //            {
    //                if (entityType.GetCustomAttribute<SysTableAttribute>() == null && (entityType.GetCustomAttribute<LogTableAttribute>() != null || entityType.GetCustomAttribute<TenantAttribute>() != null))
    //                    continue;
    //            }
    //            else if (config.ConfigId.ToString() == SqlSugarConst.LogConfigId) // 日志库
    //            {
    //                if (entityType.GetCustomAttribute<LogTableAttribute>() == null)
    //                    continue;
    //            }
    //            else
    //            {
    //                var att = entityType.GetCustomAttribute<TenantAttribute>(); // 自定义的库
    //                if (att == null || att.configId.ToString() != config.ConfigId.ToString()) continue;
    //            }

    //            var instance = Activator.CreateInstance(seedType);
    //            var hasDataMethod = seedType.GetMethod("HasData");
    //            var seedData = ((IEnumerable)hasDataMethod?.Invoke(instance, null))?.Cast<object>();
    //            if (seedData == null) continue;

    //            var entityInfo = dbProvider.EntityMaintenance.GetEntityInfo(entityType);
    //            if (entityInfo.Columns.Any(u => u.IsPrimarykey))
    //            {
    //                // 按主键进行批量增加和更新
    //                var storage = dbProvider.StorageableByObject(seedData.ToList()).ToStorage();
    //                storage.AsInsertable.ExecuteCommand();
    //                storage.AsUpdateable.ExecuteCommand();
    //            }
    //            else
    //            {
    //                // 无主键则只进行插入
    //                if (!dbProvider.Queryable(entityInfo.DbTableName, entityInfo.DbTableName).Any())
    //                    dbProvider.InsertableByObject(seedData.ToList()).ExecuteCommand();
    //            }
    //        }
    //    }
    //}
}
